from fastapi import Request
from pydantic import BaseModel
from tortoise.transactions import atomic, in_transaction

from service import RepositoryService, UserService, CollaboratorService, BookService
from common.result.Result import Result
from common.enum import BaseEnum
from common.const import BaseConstant
from util.redis import Redis
from util.str import Str
from util.log import Log
from util.token import Token
from util.time import Time

class Body(BaseModel):
    repositoryShortUri: str
    bookShortUri: str

async def GetBook(req: Request, repositoryShortUri: str, bookShortUri: str):
    try:
        if Str.isBlank(repositoryShortUri, bookShortUri):
            Log.error('参数为空，检查参数')
            return Result.error(BaseEnum.PARAMETER_INVALID_ERROR)
        

        # 获取 repository
        repository = await RepositoryService.getRepositoryByShortUri(repositoryShortUri)
        if repository == None:
            Log.error('repository 不存在')
            return Result.error(BaseEnum.REPOSITORY_NOT_EXISTS_ERROR)

        token = req.headers.get("token")
        user = await UserService.getUserByToken(token)
        
        # 判断仓库是否允许用户读
        flag = await RepositoryService.getUserReadPermission(repository, user.id if user else 0)
        if flag == False:
            Log.error('该 repository 不允许该用户读')
            return Result.error(BaseEnum.REPOSITORY_NO_READ_PERMISSION_ERROR)
        
        if flag == True:
            key = BaseConstant.BOOK_KEY % bookShortUri
            book = Redis.getItem(key)
            if book != None:
                return Result.success(book.get("book"))

            # 获取 book
            book = await BookService.getBookByShortUri(bookShortUri)
            if book == None:
                Log.error('book 不存在')
                return Result.error(BaseEnum.BOOK_NOT_EXISTS_ERROR)
        
            # Book 对象要转为 dict 才能被 JSON 序列化
            Redis.setItem(key, {
                "book": dict(book)
            }, 60 * 60)

            return Result.success(book)
        else:
            return Result.error(BaseEnum.REPOSITORY_NO_READ_PERMISSION_ERROR)
    except Exception as e:
        Log.error('获取 book 异常', e)
        return Result.error(BaseEnum.SERVICE_ERROR)